#!/usr/bin/env python
# -*- coding: utf-8 -*-
# time: 2022/10/19 15:11
# file: login.py
# author: lotus163
import datetime

import kaptcha
from fastapi import APIRouter, Depends
from fastapi.security import OAuth2PasswordRequestForm
from starlette.requests import Request

from backend.core.deps import LoginDepends, get_redis, UserDepends, get_user_depends
from backend.core.redis import MyRedis
from backend.core.result import ResultLogin, ResultCaptcha, ResultUserInfo, ResultData, result_success, Result
from backend.crud import MenuDao
from backend.schemas import LoginForm, Token, LoginInforSch
from backend.service.system.captcha import CaptchaService
from backend.service.system.login import LoginService
from backend.service.system.menu import MenuService
from backend.service.system.router import RouterService
from backend.utils.string_util import get_uuid

router = APIRouter(tags=["登录"])


def get_uuid_img():
    """获取uuid和img的base64"""
    code, image = kaptcha.Captcha().digit()
    img = image.split(",")[-1]
    uuid = get_uuid()
    return uuid, code, img


@router.post("/login", response_model=ResultLogin, summary='登录')
async def login(form: LoginForm, login_depends: LoginDepends = Depends(LoginDepends)):
    """
    登录
    先验证码，验证码失效或错误都会抛出异常。
    再验证用户名密码，成功则生成token，返回。
    """
    captcha_service = CaptchaService(login_depends.redis)
    # 只有需要验证码的情况才有验证码验证
    captchaEnabled = await captcha_service.is_captcha_enabled()
    if captchaEnabled:
        await captcha_service.validate_captcha(form.uuid, form.code)
    else:
        form.uuid = get_uuid()
    # 前面没有抛出异常，则验证密码并获取token
    token = await LoginService(form, login_depends).validate_login_and_get_token()
    return result_success(token=token)


@router.post("/logout", response_model=Result, summary='登出')
async def logout(user_depends: UserDepends = Depends(get_user_depends)):
    await user_depends.redis.delete_login_tokens(user_depends.login_user.uuid)
    return result_success()


@router.get("/getInfo", response_model=ResultUserInfo, summary='获取用户信息')
async def get_info(user_depends: UserDepends = Depends(get_user_depends)):
    user = user_depends.login_user.user
    permissions = user_depends.login_user.data_scope.permissions
    roles_key = [role.roleKey for role in user.roles]
    return result_success(user=user, roles=roles_key, permissions=permissions)


@router.get("/getRouters", response_model=ResultData, response_model_exclude_none=True, summary='获取路由信息')
async def get_routers(user_depends: UserDepends = Depends(get_user_depends)):
    if user_depends.login_user.user.admin:
        menus_sch = await MenuDao.get_list_sch()
    else:
        # 个人的菜单权限
        menus_sch = await MenuDao.get_list_sch(menuId__in=user_depends.login_user.data_scope.roles_menus_ids)
    routers = RouterService().get_routers(menus_sch)
    return result_success(data=routers)


@router.post("/register", response_model=Result, summary='用户注册')
async def register(request: Request):
    return result_success()


@router.get("/captchaImage", response_model=ResultCaptcha, response_model_exclude_none=True, summary='获取验证码')
async def get_captcha_code(redis: MyRedis = Depends(get_redis)):
    """获取验证码"""
    captcha_service = CaptchaService(redis)
    captchaEnabled = await captcha_service.is_captcha_enabled()
    if captchaEnabled:
        uuid, code, img = await captcha_service.get_uuid_img()
        # 返回结果
        return result_success(captchaEnabled=captchaEnabled, uuid=uuid, img=img)
    else:
        return result_success(captchaEnabled=captchaEnabled)


@router.post("/token", response_model=Token, summary='swagger登录')
async def login_access_token(form: OAuth2PasswordRequestForm = Depends(),
                             login_depends: LoginDepends = Depends(LoginDepends)):
    login_form = LoginForm(username=form.username, password=form.password, code="", uuid=get_uuid())
    # 验证密码并获取token
    token = await LoginService(login_form, login_depends).validate_login_and_get_token()
    return {"access_token": token, "token_type": "bearer"}
